using Microsoft.EntityFrameworkCore;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Config;
using net_work.Data.DTO.Sys;
using net_work.Data.Entity.Sys;
using net_work.Data.VO.Sys;
using net_work.IRepository.Sys;

namespace net_work.Repository.Sys;

public class DepartmentRepository(ApplicationDbContext dbContext)
    : Repository<Department>(dbContext), IDepartmentRepository
{
    public async Task<long> InsertAsync(DepartmentAddRequest departmentAddRequest)
    {
        var existingDepartment =
            await dbContext.Departments.IgnoreQueryFilters()
                .FirstOrDefaultAsync(x => x.DepName == departmentAddRequest.DepName);
        if (existingDepartment != null)
        {
            return -1;
        }

        var newDepartment = new Department
        {
            DepName = departmentAddRequest.DepName,
            DepPhone = departmentAddRequest.DepPhone,
            DepAddr = departmentAddRequest.DepAddr,
            DepEmail = departmentAddRequest.DepEmail,
            HeadTeacherId = departmentAddRequest.HeadTeacherId,
            CollegeId = departmentAddRequest.CollegeId,
            Remark = departmentAddRequest.Remark
        };
        await dbContext.Departments.AddAsync(newDepartment);
        await dbContext.SaveChangesAsync();
        return newDepartment.Id;
    }

    public async Task<bool> UpdateAsync(DepartmentUpdateRequest departmentUpdateRequest)
    {
        var departments = await dbContext.Departments
            .IgnoreQueryFilters()
            .Where(d => d.Id == departmentUpdateRequest.Id || d.DepName == departmentUpdateRequest.DepName)
            .ToListAsync();

        var conflictDepartment = departments.FirstOrDefault(x => x.Id != departmentUpdateRequest.Id);
        if (conflictDepartment != null)
        {
            return false;
        }

        var existingDepartment = departments.FirstOrDefault(x => x.Id == departmentUpdateRequest.Id);
        if (existingDepartment == null)
        {
            return false;
        }

        existingDepartment.Remark = departmentUpdateRequest.Remark;
        existingDepartment.DepName = departmentUpdateRequest.DepName;
        existingDepartment.DepPhone = departmentUpdateRequest.DepPhone;
        existingDepartment.DepAddr = departmentUpdateRequest.DepAddr;
        existingDepartment.DepEmail = departmentUpdateRequest.DepEmail;
        existingDepartment.HeadTeacherId = departmentUpdateRequest.HeadTeacherId;
        existingDepartment.CollegeId = departmentUpdateRequest.CollegeId;

        await dbContext.SaveChangesAsync();
        return true;
    }

    public Task<PagedResult<DepartmentResult>> GetDepartmentPagedAsync(PagedRequest request)
    {
        var query = from department in dbContext.Departments
            join college in dbContext.Colleges on department.CollegeId equals college.Id
            join teacher in dbContext.Teachers on department.HeadTeacherId equals teacher.Id into TeacherGroup
            from teacher in TeacherGroup.DefaultIfEmpty()
            join person in dbContext.People on teacher.PsnId equals person.Id into PersonGroup
            from person in PersonGroup.DefaultIfEmpty()
            select new DepartmentResult
            {
                Id = department.Id,
                DepName = department.DepName,
                DepPhone = department.DepPhone,
                DepAddr = department.DepAddr,
                DepEmail = department.DepEmail,
                HeadTeacherId = department.HeadTeacherId,
                HeadTeacherName = person.PsnName,
                CollegeId = department.CollegeId,
                CollegeName = college.ColleName,
                Remark = department.Remark,
                CreatedTime = department.CreatedTime,
                UpdatedTime = department.UpdatedTime,
                CreatedBy = department.CreatedBy,
                UpdatedBy = department.UpdatedBy,
                DelFlag = department.DelFlag
            };

        return GetPagedQueryResultAsync(query, request);
    }
}